package org.xinjiang.data.migration.flush.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.xinjiang.data.migration.common.response.Result;
import org.xinjiang.data.migration.flush.convert.*;
import org.xinjiang.data.migration.flush.service.ISettingFlushService;
import org.xinjiang.data.migration.flush.service.ISettingQueryService;
import org.xinjiang.data.migration.flush.service.ISettingSaveService;
import org.xinjiang.data.migration.hainan.enums.KeyColumnEnum;
import org.xinjiang.data.migration.xinjiang.entity.WegovOrgMemberTeam;
import org.xinjiang.data.migration.xinjiang.enums.GzryConditionEnum;
import org.xinjiang.data.migration.xinjiang.enums.KeyIdEnum;

import java.util.*;

@Service
public class SettingFlushServiceImpl implements ISettingFlushService {

    @Autowired
    private ISettingQueryService queryService;

    @Autowired
    private ISettingSaveService saveService;

    private Integer size = 10;

    @Autowired
    private BaseConvert userConvert;

    @Autowired
    private DepartConvert departConvert;

    @Autowired
    private DepartParentConvert departParentConvert;


    @Autowired
    private SocialWorkerConvert socialWorkerConvert;

    @Autowired
    private VolunteerConvert volunteerConvert;

    @Autowired
    private WorkingPersonnelConvert personnelConvert;

    @Override
    public Result<Integer> depart(List<String> ids) {
        Map<String, Object> data = GzryConditionEnum.TABLE_SYS_DEPART.getData();
        Integer integer = flushALLData(KeyIdEnum.TABLE_SYS_DEPART, KeyColumnEnum.TABLE_SYS_DEPART, departConvert, ids, data);
        return Result.ok(integer);
    }

    public Result<Integer> departParent(List<String> ids) {
        Integer integer = flushDepartParentData(ids);
        return Result.ok(integer);
    }

    @Override
    public Result<Integer> user(List<String> ids) {
        Map<String, Object> data = GzryConditionEnum.TABLE_SYS_USER.getData();
        Integer integer = flushALLData(KeyIdEnum.TABLE_SYS_USER, KeyColumnEnum.TABLE_SYS_USER, userConvert, ids, data);
        return Result.ok(integer);
    }

    /**
     * @param idEnum     出库枚举，转换Service
     * @param columnEnum 入库枚举，转换Service
     * @param convert    转换对象
     * @param sourceIds  出口的id数据
     * @return 返回失败数量
     */
    private <S, T> Integer flushALLData(KeyIdEnum idEnum, KeyColumnEnum columnEnum, BaseConvert<S, T> convert, List<String> sourceIds, Map<String, Object> andCondition) {
        int current = 1;
        boolean hasPrevious = false;
        int result = 0;
        do {
            IPage<S> page = new Page<>(current, size);
            IPage<S> iPage = queryService.queryPageList(idEnum, page, sourceIds, andCondition);
            if (iPage instanceof Page) {
                hasPrevious = ((Page) iPage).hasNext();
            }
            List<S> records = iPage.getRecords();
            Integer integer = saveService.saveBatch(columnEnum, convert.converts(records));
            result += integer;
            current++;
        } while (hasPrevious);

        return result;
    }


    private <S, T> Integer flushALLData(KeyIdEnum idEnum, KeyColumnEnum columnEnum, BaseConvert<S, T> convert, List<String> sourceIds) {
        return flushALLData(idEnum, columnEnum, convert, sourceIds, null);
    }

    /**
     * 更新部门父id
     *
     * @param sourceIds
     * @param <S>
     * @param <T>
     * @return
     */
    private <S, T> Integer flushDepartParentData(List<String> sourceIds) {
        int current = 1;
        boolean hasPrevious = false;
        int result = 0;
        do {
            IPage<WegovOrgMemberTeam> page = new Page<>(current, size);
            IPage<WegovOrgMemberTeam> iPage = queryService.queryPageList(KeyIdEnum.TABLE_SYS_DEPART_PARENT, page, sourceIds, GzryConditionEnum.TABLE_SYS_DEPART_PARENT.getData());
            if (iPage instanceof Page) {
                hasPrevious = ((Page) iPage).hasNext();
            }
            BaseConvert convert = departParentConvert;
            Collection<T> converts = convert.converts(iPage.getRecords());
            Integer integer = saveService.updateBatchDepartParent(KeyColumnEnum.TABLE_SYS_DEPART, converts);
            result += integer;
            current++;
        } while (hasPrevious);

        return result;
    }

    /**
     * 工作人员
     *
     * @param ids
     * @return
     */
    @Override
    public Result<Integer> workingPersonnel(List<String> ids, boolean increment) {
        Integer workingPersonnel = flushALLData(KeyColumnEnum.TABLE_MST_CORRECTIONTEAM_FUNCTIONARY, GzryConditionEnum.TABLE_MST_CORRECTIONTEAM_FUNCTIONARY, ids, KeyIdEnum.TABLE_MST_CORRECTIONTEAM_FUNCTIONARY, personnelConvert, increment);
        return Result.ok(workingPersonnel);
    }


    /**
     * 社会工作者
     *
     * @param ids
     * @return
     */
    @Override
    public Result<Integer> socialWorker(List<String> ids, boolean increment) {
        Integer integer = flushALLData(KeyColumnEnum.TABLE_MST_COMMUNITY_WORKER, GzryConditionEnum.TABLE_MST_COMMUNITY_WORKER, ids, KeyIdEnum.TABLE_MST_COMMUNITY_WORKER, socialWorkerConvert, increment);
        return Result.ok(integer);
    }

    /**
     * 志愿者
     *
     * @param ids
     * @return
     */
    @Override
    public Result<Integer> volunteer(List<String> ids, boolean increment) {
        Integer integer = flushALLData(KeyColumnEnum.TABLE_MST_COMMUNITY_VOLUNTEER, GzryConditionEnum.TABLE_MST_COMMUNITY_VOLUNTEER, ids, KeyIdEnum.TABLE_MST_COMMUNITY_VOLUNTEER, volunteerConvert, increment);
        return Result.ok(integer);
    }

    /**
     * 针对源数据库  SQJZ_GZRY
     *
     * @param columnEnum
     * @param conditionEnum
     * @param ids
     * @param keyIdEnum
     * @param convert
     * @return
     */
    private Integer flushALLData(KeyColumnEnum columnEnum, GzryConditionEnum conditionEnum, List<String> ids, KeyIdEnum keyIdEnum, BaseConvert convert, boolean increment) {
        Map<String, Object> data = new HashMap<>(conditionEnum.getData());
        if (increment) {
            Set set = saveService.queryNotIds(columnEnum);
            if (set.size() >= 1000) {
                data.put(GzryConditionEnum.NOT_PAGE, set.size() / size);
            } else {// oracle  不支持大于1000的 not in
                data.put(GzryConditionEnum.NOT, set);
            }
        }
        return flushALLData(keyIdEnum, columnEnum, convert, ids, data);
    }

    /**
     * 清空表数据
     *
     * @return
     */
    @Override
    public Result<Integer> clearTabelData() {
        return Result.ok(saveService.clearTabelData());
    }

    /**
     * 更新创建人修改人id
     *
     * @return
     */
    @Override
    public Result<Integer> updateCreateUpdateBy() {
        return Result.ok(saveService.updateCreateUpdateBy(size));
    }

    /**
     * 创建用户不关系表,会清空原有关系
     *
     * @return
     */
    @Override
    public Result<Integer> updateCreateUserDerart() {
        return Result.ok(saveService.updateCreateUserDerart(size));
    }

    @Override
    public Result<Integer> pullAll() {
        Integer depart = depart(null).getData();
        Integer departParent = departParent(null).getData();
        Integer user = user(null).getData();
        Integer workingPersonnel = workingPersonnel(null, false).getData();
        Integer socialWorker = socialWorker(null, false).getData();
        Integer volunteer = volunteer(null, false).getData();
        Integer updateCreateUpdateBy = updateCreateUpdateBy().getData();
        return Result.ok("部门失败数据:" + depart + "部门子父失败数据:" + departParent + "用户失败数据:" + user + "工作人员失败数据:" + workingPersonnel + "社会工作者失败数据:" + socialWorker + "志愿者失败数据:" + volunteer + "更新创建修改人id:" + updateCreateUpdateBy, depart + departParent + user + workingPersonnel + socialWorker + volunteer + updateCreateUpdateBy);
    }
}
